package org.lboot.flow.processor.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.lboot.flow.FlowCtl;
import org.lboot.flow.constant.FlowNodeTypeConst;
import org.lboot.flow.constant.FlowWorkStatusConst;
import org.lboot.flow.constant.FlowWorkStatusEnum;
import org.lboot.flow.event.system.FlowBlockEvent;
import org.lboot.flow.event.system.FlowStartEvent;
import org.lboot.flow.model.FlowModel;
import org.lboot.flow.model.node.BaseModel;
import org.lboot.flow.model.node.SubFlowModel;
import org.lboot.flow.module.define.FlowDefine;
import org.lboot.flow.module.define.FlowDefineService;
import org.lboot.flow.module.work.FlowWork;
import org.lboot.flow.module.work.FlowWorkService;
import org.lboot.flow.module.work.params.FlowStartParams;
import org.lboot.flow.module.work.params.FlowTaskParams;
import org.lboot.flow.parser.FlowNodeParser;
import org.lboot.flow.processor.FlowNodeProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Slf4j
@Service
@AllArgsConstructor
public class SubFlowNodeProcessorImpl implements FlowNodeProcessor {
    // 流程节点解析器
    FlowNodeParser flowNodeParser;

    FlowWorkService flowWorkService;

    FlowDefineService defineService;

    @Resource
    ApplicationContext context;

    FlowCtl flowCtl;

    @Override
    public String getNodeType() {
        return FlowNodeTypeConst.SUB_FLOW_NODE;
    }

    public FlowWork startSubFlow(String rootFlowId){
        return null;
    }

    @Override
    @SneakyThrows
    public void process(FlowWork flowWork, FlowTaskParams taskParams) {
        // 流程执行到下一步
        BaseModel currentNode = flowWork.getNodeModel(flowWork.getCurrentNodeId());
        // 获取子流程节点
        SubFlowModel subFlowModel = (SubFlowModel) currentNode;
        // 查询流程定义是否存在
        List<FlowDefine> defines = defineService.getFlowByCode(subFlowModel.getFlowDefineCode());
        // 是否允许跨域流程
        if (subFlowModel.getEnableCross()){
            // 本地是否存在
        }else {
            // 不允许跨域
            //不存在流程定义 ==> 流程进入阻塞状态
            if (defines.isEmpty()){
                // 发布流程阻塞事件
                context.publishEvent(new FlowBlockEvent(this, flowWork));
            }
            // 存在流程定义 ==> 流程进入等待状态 . 且发起子流程
            FlowWork newFlow = new FlowWork();
            BeanUtil.copyProperties(flowWork, newFlow,  CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
            FlowStartParams startParams = new FlowStartParams();

        }
        // 开启子流
        FlowWork oldFlow = new FlowWork();
        BeanUtil.copyProperties(flowWork,oldFlow, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));

        // 获取流程
        String startFlowCode = subFlowModel.getFlowDefineCode();
        // 定义流程启动参数
        FlowStartParams startParams = new FlowStartParams();
        // 复制流程信息
        BeanUtil.copyProperties(flowWork,startParams,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        startParams.setFlowCode(startFlowCode);
        // 流程启动
        flowCtl.startProcess(startParams);
        // 流程切换为等待 并 挂起
        flowWork.setFlowWorkStatus(FlowWorkStatusEnum.IN_WAIT.value);
        flowWork.setStatus(0);
        flowWorkService.updateOne(flowWork);
    }

    @Override
    public void back(FlowWork flowWork, FlowTaskParams taskParams) {

    }
}
